package com.gitee.wsl.common.chart.sample.bar

import android.graphics.Canvas
import android.graphics.Paint
import com.gitee.wsl.common.chart.ChartEnum
import com.gitee.wsl.common.chart.adapter.DataSource
import com.gitee.wsl.common.chart.adapter.SelectItemChartAdapter
import com.gitee.wsl.common.chart.listener.click.BarPosition
import com.gitee.wsl.common.chart.listener.click.PlotBarPosition
import com.gitee.wsl.common.chart.render.background.axis.line.CategoryLineAxis
import com.gitee.wsl.common.chart.render.background.axis.line.DataLineAxis
import com.gitee.wsl.common.chart.render.foreground.PlotCustomLine
import com.gitee.wsl.common.chart.render.foreground.info.Anchor
import com.gitee.wsl.common.chart.render.shape.bar.FlatBar
import com.gitee.wsl.common.chart.sample.AbstractAxesChart
import com.gitee.wsl.common.chart.sample.bar.adapter.BarChartAdapter
import com.gitee.wsl.common.chart.sample.bar.model.BarData
import com.gitee.wsl.common.ui.draw.type.GridDirection
import com.gitee.wsl.android.ui.ext.type.textHeight
import com.gitee.wsl.android.ui.ext.type.textWidth
import com.gitee.wsl.math.Math
import com.gitee.wsl.jvm.math.add
import com.gitee.wsl.jvm.math.div
import com.gitee.wsl.jvm.math.mul
import com.gitee.wsl.jvm.math.sub
import timber.log.Timber

open class BarChart(val adapter:BarChartAdapter= BarChartAdapter()) : AbstractAxesChart(adapter),
    SelectItemChartAdapter<BarData> by adapter {

    // 柱形基类
    var flatBar = FlatBar()

    // 数据源
    var dataSet by DataSource(adapter)

    //用于绘制定制线(分界线)
     val customLine: PlotCustomLine = PlotCustomLine()

    //批注
    var anchorSet: List<Anchor> = emptyList()

    //值与轴最小值相等
     var isEqualAxisMin = false

    //标签和对象依哪种风格居中显示
    var barCenterStyle = ChartEnum.BarCenterStyle.SPACE
    
    /**
     * 比较传入的各个数据集，找出最大数据个数
     * @return 最大数据个数
     */
     fun getDataAxisDetailSetMaxSize(): Int {
        // 得到最大size个数
        var dsetMaxSize = 0
        val size = dataSet.size
        for (i in 0 until size) {
            if (dsetMaxSize < dataSet[i].dataSet.size) dsetMaxSize = dataSet[i].dataSet.size
        }
        return dsetMaxSize
    }

     override fun drawClipDataAxisGridlines(canvas: Canvas, dataAxis:DataLineAxis, pos: ChartEnum.AxisLocation) {

        // 数据轴数据刻度总个数
        val tickCount: Int = dataAxis.axisTickCount
        val labeltickCount = tickCount + 1
        if (0 == tickCount) {
            Timber.d( "数据轴数据源为0!")
            return
        }

        // 与柱形图不同，无须多弄一个
        var XSteps = 0.0f
        var YSteps = 0.0f
        // 标签轴(X 轴)
        var axisX = 0.0f
        var axisY = 0.0f

        // 标签
        var currentTickLabel = 0.0f
        // 轴位置
        //val pos: ChartEnum.AxisLocation = getDataAxisLocation()
        when (pos) {
            ChartEnum.AxisLocation.LEFT, ChartEnum.AxisLocation.RIGHT, ChartEnum.AxisLocation.VERTICAL_CENTER -> {
                YSteps = getVerticalYSteps(tickCount)
                axisX = getAxisXPos(pos)
                axisY = bodyViewport.bottom
            }
            ChartEnum.AxisLocation.TOP, ChartEnum.AxisLocation.BOTTOM, ChartEnum.AxisLocation.HORIZONTAL_CENTER -> {
                XSteps = getVerticalXSteps(tickCount)
                axisY = getAxisYPos(pos)
                axisX =  bodyViewport.left
            }
        }

         plotGrid.drawClipDataAxisGridlines(canvas, dataAxis, bodyViewport, XSteps, YSteps, axisX, axisY, labeltickCount, pos,true)


         /*lstDataTick.clear()
         //绘制
         for (i in 0 until labeltickCount) {
             when (pos) {
                 ChartEnum.AxisLocation.LEFT, ChartEnum.AxisLocation.RIGHT, ChartEnum.AxisLocation.VERTICAL_CENTER -> {
                     // 依起始数据坐标与数据刻度间距算出上移高度
                     currentY = MathExt.sub( bodyViewport.bottom, MathExt.mul(i.toFloat(), YSteps))

                     // 从左到右的横向网格线
                     plotGrid.renderHorizontalGridLines(canvas, dataAxis.isPrimaryTick(i), bodyViewport.left, bodyViewport.right, i, tickCount, YSteps, currentY)

                     //if(!dataAxis.isShowAxisLabels())continue;

                     // 标签
                     currentTickLabel = add(dataAxis.axisMin, i * dataAxis.axisSteps)
                     lstDataTick.add(PlotAxisTick(i, axisX, currentY, currentTickLabel.toString()))
                 }
                 ChartEnum.AxisLocation.TOP, ChartEnum.AxisLocation.BOTTOM, ChartEnum.AxisLocation.HORIZONTAL_CENTER -> {
                     //bar
                     // 依起始数据坐标与数据刻度间距算出上移高度
                     currentX = add(axisX, MathExt.mul(i.toFloat(), XSteps))

                     //绘制竖向网格线
                     plotGrid.renderVerticalGridLines(canvas, bodyViewport.top,  bodyViewport.bottom, i, tickCount, XSteps, currentX)

                     // if(!dataAxis.isShowAxisLabels())continue;

                     // 画上标签/刻度线
                     currentTickLabel = add(dataAxis.axisMin, i * dataAxis.axisSteps)
                     lstDataTick.add(PlotAxisTick(i, currentX, axisY, currentTickLabel.toString()))
                 }
             }
         } //end for*/
    }


    /**
     * 绘制底部标签轴
     */
    override fun drawClipCategoryAxisGridlines(canvas: Canvas,
                                       categoryAxis:CategoryLineAxis,
                                       pos: ChartEnum.AxisLocation
    ) {
        // 得到标签轴数据集
        val dataSet: List<String> = categoryAxis.dataSet

        val tickCount = dataSet.size

        if (0 == tickCount) {
            Timber.d( "分类轴数据源为0!")
            return
        }

        val labeltickCount = getCategoryAxisLabelTickCount(categoryAxis)

        // 与柱形图不同，无须多弄一个
        var XSteps = 0.0f
        var YSteps = 0.0f
        // 标签轴(X 轴)
        var axisX = 0.0f
        var axisY = 0.0f

        //val pos: ChartEnum.AxisLocation = getCategoryAxisLocation()
        if (ChartEnum.AxisLocation.LEFT == pos || ChartEnum.AxisLocation.RIGHT == pos || ChartEnum.AxisLocation.VERTICAL_CENTER == pos) {
            //line
            YSteps = getVerticalYSteps(labeltickCount)
            axisX = getAxisXPos(pos)
            axisY =  bodyViewport.bottom
        } else { //TOP BOTTOM
            // 依传入的分类个数与轴总宽度算出要画的分类间距数是多少
            // 总宽度 / 分类个数 = 间距长度    //getAxisScreenWidth()
            XSteps = getVerticalXSteps(labeltickCount)
            axisY = getAxisYPos(pos)
            axisX =  bodyViewport.left
        }

        plotGrid.drawClipCategoryAxisGridlines(canvas, categoryAxis, bodyViewport, barCenterStyle, XSteps, YSteps, axisX, axisY,get3DOffsetX(),get3DBaseOffsetY(),get3DBaseOffsetX(),tickCount)

        /*lstCateTick.clear()
        var labelX: Float
        var labelY: Float
        var showTicks = true

        //绘制
        for (i in 0 until tickCount) {
            when (pos) {
                ChartEnum.AxisLocation.LEFT, ChartEnum.AxisLocation.RIGHT, ChartEnum.AxisLocation.VERTICAL_CENTER -> {
                    // 依初超始Y坐标与分类间距算出当前刻度的Y坐标
                    currentY = MathExt.sub(axisY, mul((i + 1).toFloat(), YSteps))

                    // 从左到右的横向网格线
                    plotGrid.renderHorizontalGridLines(canvas, false, bodyViewport.left, bodyViewport.right, i, tickCount, YSteps, currentY)
                    if (!categoryAxis.isShowAxisLabels) continue
                    labelY = currentY
                    run {
                        currentX = MathExt.sub(axisX, get3DOffsetX())
                        labelX = currentX
                    }
                    if (ChartEnum.BarCenterStyle.SPACE == barCenterStyle) {
                        //if(i == tickCount - 1)continue;
                        if (i == tickCount - 1) showTicks = false
                        labelY = add(currentY, MathExt.div(YSteps, 2f))
                    }

                    // 分类
                    lstCateTick.add(PlotAxisTick(currentX, currentY, categoryAxis.dataSet[i], labelX, labelY, showTicks))
                }
                ChartEnum.AxisLocation.TOP, ChartEnum.AxisLocation.BOTTOM, ChartEnum.AxisLocation.HORIZONTAL_CENTER -> {
                    // 依初超始X坐标与分类间距算出当前刻度的X坐标
                    currentX = add( bodyViewport.left, mul((i + 1).toFloat(), XSteps))

                    //绘制竖向网格线
                    plotGrid.renderVerticalGridLines(
                        canvas, bodyViewport.top,  bodyViewport.bottom,
                        i, tickCount, XSteps, currentX
                    )
                    if (!categoryAxis.isShowAxisLabels) continue
                    val currentY2: Float = add(axisY, get3DBaseOffsetY())
                    currentX = MathExt.sub(currentX, get3DBaseOffsetX())
                    labelX = currentX
                    labelY = currentY2
                    if (ChartEnum.BarCenterStyle.SPACE == barCenterStyle) {
                        if (i == tickCount - 1) {
                            showTicks = false
                        }
                        labelX = MathExt.sub(currentX, MathExt.div(XSteps, 2f))
                    }
                    lstCateTick.add(PlotAxisTick(currentX, currentY2, dataSet[i], labelX, labelY, showTicks))
                }
            }
        } //end for*/
    }

    override fun getCategoryAxisLabelTickCount(categoryAxis:CategoryLineAxis): Int {
        val tickCount: Int = categoryAxis.dataSet.size
        var labeltickCount = 0
        labeltickCount = if (0 == tickCount) {
            Timber.d("分类轴数据源为0!")
            return labeltickCount
        } else if (1 == tickCount) { // label仅一个时右移
            tickCount
        } else {
            if (xCoordFirstTickmarksBegin) {
                if (ChartEnum.BarCenterStyle.SPACE == barCenterStyle) {
                    tickCount
                } else {
                    tickCount + 1
                }
            } else {
                tickCount - 1
            }
        }
        return labeltickCount
    }

    /**
     * 绘制横向柱形图
     * @throws InterruptedException 例外
     */
    protected open fun drawHorizontalBar(
        canvas: Canvas,
        dataAxis: DataLineAxis,
        categoryAxis: CategoryLineAxis
        ): Boolean {
        if ( dataSet.isEmpty()) return false

        // 得到Y 轴分类横向间距高度
        val YSteps: Float = getVerticalYSteps(getCateTickCount(categoryAxis))
        val barInitX: Float =  bodyViewport.left
        val barInitY: Float =  bodyViewport.bottom

        // 依柱形宽度，多柱形间的偏移值 与当前数据集的总数据个数得到当前分类柱形要占的高度
        val barNumber = getDatasetSize(dataSet,dataAxis)
        if (barNumber <= 0) return false
        var currNumber = 0
        val ret = flatBar.getBarHeightAndMargin(YSteps, barNumber)
        if (null == ret || ret.size != 2) {
            Timber.d( "分隔间距计算失败.")
            return false
        }
        val barHeight = ret[0]
        val barInnerMargin = ret[1]
        val labelBarUseHeight: Float = Math.add(
            Math.mul(barNumber.toFloat(), barHeight),
            Math.mul(Math.sub(barNumber.toFloat(), 1f), barInnerMargin)
        )
        var bv = 0.0f
        val dataAxisStd = getHPDataAxisStdX(dataAxis)
        var itemLabelWidth = 0f
        var barLeft = 0.0f
        var barBottom = 0.0f
        var barTop = 0f
        var barRight = 0f
        var labelLeftX: Float
        var labelLeftY: Float
        var currLabelY: Float
        var drawBarButtomY: Float
        var rightX: Float
        for (i in 0 until barNumber) {
            // 得到分类对应的值数据集
            val bd = dataSet[i]
            val barValues = bd.dataSet
            val barDataColor = bd.dataColor
            // 设置成对应的颜色
            flatBar.barPaint.color = bd.color

            // 画同分类下的所有柱形
            val vSize = barValues.size
            for (j in 0 until vSize) {
                bv = barValues[j]
                setBarDataColor(flatBar.barPaint, barDataColor, j, bd.color)
                currLabelY = Math.sub(barInitY, Math.mul((j + 1).toFloat(), YSteps))
                drawBarButtomY = if (ChartEnum.BarCenterStyle.SPACE == barCenterStyle) {
                    Math.add(Math.add(currLabelY, Math.div(YSteps, 2f)), labelBarUseHeight / 2)
                } else {
                    Math.add(currLabelY, labelBarUseHeight / 2)
                }
                drawBarButtomY = Math.sub(drawBarButtomY, Math.add(barHeight, barInnerMargin) * currNumber)
                rightX = getHPValPosition(bv,dataAxis)
                labelLeftX = rightX
                val label: String = getFormatterItemLabel(bv)
                if (flatBar.isShowItemLabel)
                    itemLabelWidth =flatBar.itemLabelPaint.textWidth( label)
                if (dataAxis.isAxisStdStatus) {
                    if (bv < dataAxis.dataAxisStd) //反向
                    {
                        barLeft = rightX
                        barTop = Math.sub(drawBarButtomY, barHeight)
                        barRight = dataAxisStd
                        barBottom = drawBarButtomY
                        labelLeftX = rightX - itemLabelWidth
                    } else {
                        barLeft = dataAxisStd
                        barTop = Math.sub(drawBarButtomY, barHeight)
                        barRight = rightX
                        barBottom = drawBarButtomY
                    }
                } else {
                    barLeft = barInitX
                    barTop = Math.sub(drawBarButtomY, barHeight)
                    barRight = rightX
                    barBottom = drawBarButtomY
                }


                // 画出柱形
                flatBar.renderBar(barLeft, barBottom, barRight, barTop, canvas)

                //保存位置
                saveBarRectFRecord(
                    i, j, barLeft + moveX, barTop + moveY,
                    barRight + moveX, barBottom + moveY
                )
                labelLeftY = Math.sub(barBottom, barHeight / 2)

                //在柱形的顶端显示上柱形的批注形状
                drawAnchor(anchorSet, i, j, canvas, labelLeftX, labelLeftY, 0.0f)

                // 柱形顶端标识
                if (!isEqualAxisMin && dataAxis.axisMin.compareTo(bv) == 0) {
                } else {
                    if (flatBar.itemLabelStyle == ChartEnum.ItemLabelStyle.BOTTOM) {
                        flatBar.renderBarItemLabel(label, barLeft, labelLeftY, canvas)
                    } else {
                        flatBar.renderBarItemLabel(label, labelLeftX, labelLeftY, canvas)
                    }
                }

                //显示焦点框
                drawFocusRect(canvas, i, j, barLeft, barTop, barRight, barBottom)
            }
            currNumber++
        }
        adapter.isRecordSetInited = true
        //画横向柱形图，竖向的定制线
        if (null != customLine) {
            customLine.setHorizontalPlot(dataAxis, bodyViewport, this.getAxisScreenWidth())
            customLine.renderHorizontalCustomlinesDataAxis(canvas)
        }
        return true
    }

    /**
     * 返回指定数据在图中的横向坐标位置
     * @param bv 数据
     * @return 坐标位置
     */
    private fun getHPValPosition(bv: Float,dataAxis: DataLineAxis): Float {
        val vaxlen = Math.sub(bv, dataAxis.axisMin)
        val valuePostion: Float = Math.mul(getPlotScreenWidth(), Math.div(vaxlen, dataAxis.axisRange))
        return Math.add( bodyViewport.left, valuePostion)
    }

    private fun getHPDataAxisStdX(dataAxis: DataLineAxis): Float {
        return if (dataAxis.isAxisStdStatus) {
            getHPValPosition(dataAxis.dataAxisStd,dataAxis)
        } else {
             bodyViewport.left
        }
    }

    /**
     * 返回指定数据在图中的竖向坐标位置
     * @param bv 数据
     * @return 坐标位置
     */
     /*fun getVPValPosition(bv: Float,dataAxis: DataLineAxis): Float {
        val vaxlen = MathExt.sub(bv, dataAxis.axisMin)
        val valuePostion: Float = MathExt.mul(getPlotScreenHeight(), MathExt.div(vaxlen, dataAxis.axisRange))
        return MathExt.sub( bodyViewport.bottom, valuePostion)
    }
*/
    /*override fun getVPDataAxisStdY(dataAxis: DataLineAxis): Float {
        return if (dataAxis.isAxisStdStatus) {
            getVPValPosition(dataAxis.dataAxisStd,dataAxis)
        } else {
             bodyViewport.bottom
        }
    }*/

     override fun getAxisXPos(location: ChartEnum.AxisLocation): Float {
        return if (GridDirection.HORIZONTAL == gridDirection && dataAxis.isAxisStdStatus && categoryAxis.isAxisStdStatus) {
            getHPDataAxisStdX(dataAxis)
        } else {
            super.getAxisXPos(location)
        }
    }

     override fun getAxisYPos(location: ChartEnum.AxisLocation): Float {
        return if (GridDirection.VERTICAL == gridDirection && dataAxis.isAxisStdStatus && categoryAxis.isAxisStdStatus) {
            getVPDataAxisStdY(dataAxis)
        } else {
            super.getAxisYPos(location)
        }
    }

    protected fun drawClipCategoryAxisLine(canvas: Canvas) {
        if (GridDirection.VERTICAL == gridDirection && dataAxis.isAxisStdStatus && categoryAxis.isAxisStdStatus) {
            val y = getVPDataAxisStdY(dataAxis)
            categoryAxis.renderAxis(canvas,  bodyViewport.left, y, bodyViewport.right, y)
        } else if (GridDirection.HORIZONTAL == gridDirection && dataAxis.isAxisStdStatus && categoryAxis.isAxisStdStatus) {
            val x = getHPDataAxisStdX(dataAxis)
            categoryAxis.renderAxis(canvas, x, bodyViewport.top, x,  bodyViewport.bottom)
        } else {
            categoryAxis.renderClipAxisLine(canvas,bodyViewport,categoryAxisLocation)
        }
    }

    /**
     * 绘制竖向柱形图
     */
    protected open fun drawVerticalBar(canvas: Canvas,
                                       dataAxis: DataLineAxis,
                                       categoryAxis: CategoryLineAxis): Boolean {
        if (dataSet.isEmpty()) return false
        // 得到分类轴数据集
        val dataSet: List<String> = categoryAxis.dataSet
        val XSteps: Float = getVerticalXSteps(getCateTickCount(categoryAxis))
        val dataAxisStd = getVPDataAxisStdY(dataAxis)
        var itemFontHeight = 0f
        if (flatBar.isShowItemLabel)
            itemFontHeight =flatBar.itemLabelPaint.textHeight
            
        val barNumber = getDatasetSize(this.dataSet,dataAxis)
        if (barNumber <= 0) return false
        var currNumber = 0
        val ret = flatBar.getBarWidthAndMargin(XSteps, barNumber)
        if (null == ret || ret.size != 2) {
            Timber.d("分隔间距计算失败.")
            return false
        }
        val barWidth = ret[0]
        val barInnerMargin = ret[1]
        val labelBarUseWidth: Float = Math.add(
            Math.mul(barNumber.toFloat(), barWidth),
            Math.mul(Math.sub(barNumber.toFloat(), 1f), barInnerMargin)
        )
        var barLeft = 0.0f
        var barBottom = 0.0f
        var barTop = 0f
        var barRight = 0f
        var currLabelX: Float
        var drawBarStartX: Float
        var topY: Float
        var labelTopX: Float
        var labelTopY: Float


        // X 轴 即分类轴
        val size = this.dataSet.size
        for (i in 0 until size) {
            // 得到分类对应的值数据集
            val bd = this.dataSet[i]
            val barValues = bd.dataSet

            //用于处理单独针对某些柱子指定颜色的情况
            val barDataColor = bd.dataColor

            // 设成对应的颜色
            flatBar.barPaint.color = bd.color

            // 画出分类对应的所有柱形
            val countChild = barValues.size
            for (j in 0 until countChild) {
                val bv = barValues[j]
                setBarDataColor(flatBar.barPaint, barDataColor, j, bd.color)
                currLabelX = Math.add( bodyViewport.left, Math.mul((j + 1).toFloat(), XSteps))
                if (ChartEnum.BarCenterStyle.SPACE == barCenterStyle) {
                    drawBarStartX = Math.sub(currLabelX, Math.div(XSteps, 2f))
                    drawBarStartX = Math.sub(drawBarStartX, labelBarUseWidth / 2)
                } else {
                    drawBarStartX = Math.sub(currLabelX, labelBarUseWidth / 2)
                }

                // 计算同分类多柱 形时，新柱形的起始X坐标
                drawBarStartX = Math.add(drawBarStartX, Math.add(barWidth, barInnerMargin) * currNumber)
                topY = getVPValPosition(bv,dataAxis)
                labelTopY = topY
                
                if (dataAxis.isAxisStdStatus) {
                    if (bv < dataAxis.dataAxisStd) //反向
                    {
                        barLeft = drawBarStartX
                        barTop = dataAxisStd
                        barRight = Math.add(drawBarStartX, barWidth)
                        barBottom = topY
                        labelTopY += itemFontHeight
                    } else {
                        barLeft = drawBarStartX
                        barTop = topY
                        barRight = Math.add(drawBarStartX, barWidth)
                        barBottom = dataAxisStd
                    }
                } else {
                    barLeft = drawBarStartX
                    barTop = topY
                    barRight = Math.add(drawBarStartX, barWidth)
                    barBottom =  bodyViewport.bottom
                }


                // 画出柱形
                flatBar.renderBar(barLeft, barBottom, barRight, barTop, canvas)

                //保存位置
                saveBarRectFRecord(
                    i, j, barLeft + moveX, barTop + moveY,
                    barRight + moveX, barBottom + moveY
                )

                //显示焦点框
                drawFocusRect(canvas, i, j, barLeft, barTop, barRight, barBottom)
                labelTopX = Math.add(drawBarStartX, barWidth / 2)

                //在柱形的顶端显示批注
                drawAnchor(anchorSet, i, j, canvas, labelTopX, labelTopY, 0.0f)

                // 在柱形的顶端显示上柱形当前值
                if (!isEqualAxisMin && dataAxis.axisMin.compareTo(bv) == 0) {

                } else {
                    if (flatBar.itemLabelStyle == ChartEnum.ItemLabelStyle.BOTTOM) {
                        flatBar.renderBarItemLabel(
                            getFormatterItemLabel(bv),
                            labelTopX,
                            barBottom,
                            canvas
                        )
                    } else {
                        flatBar.renderBarItemLabel(
                            getFormatterItemLabel(bv),
                            labelTopX, labelTopY, canvas
                        )
                    }
                }
            }
            currNumber++
        }
        adapter.isRecordSetInited = true

        //画竖向柱形图的定制线
        if (null != customLine) {
            customLine.setVerticalPlot(dataAxis, bodyViewport, getAxisScreenHeight())
            customLine.renderVerticalCustomlinesDataAxis(canvas)
        }
        return true
    }

     override fun drawClipPlot(canvas: Canvas,
                               dataAxis: DataLineAxis,
                               categoryAxis: CategoryLineAxis) {
        when (gridDirection) {
            GridDirection.HORIZONTAL -> drawHorizontalBar(canvas,dataAxis,categoryAxis)
            GridDirection.VERTICAL -> drawVerticalBar(canvas,dataAxis,categoryAxis)
        }
    }

     override fun drawClipLegend(canvas: Canvas) {
        //plotLegend.renderBarKey(canvas, mDataSet)
    }

    /////////////////////////////////////////////////////////////////////////////////////

    /////////////////////////////////////////////////////////////////////////////////////
    protected fun getDatasetSize(dataSource: List<BarData>,
                                 dataAxis: DataLineAxis): Int {
       
        var ret = dataSource.size
        val count = ret
        
        // X 轴 即分类轴
        for (i in 0 until count) {
            val bd = dataSource[i]
            val barValues = bd.dataSet
            if (barValues.size == 1) {
                if (barValues[0].compareTo(dataAxis.axisMin) == 0) 
                    ret--
            }
        }
        return ret
    }


    /**
     * 对于有为单个柱形设置颜色的情况，以这个函数来为画笔设置相应的颜色
     * @param paint            柱形画笔
     * @param lstDataColor    数据颜色集
     * @param currNumber    当前序号
     * @param defaultColor    默认的柱形颜色
     */
    protected fun setBarDataColor(
        paint: Paint,
        lstDataColor: List<Int>,
        currNumber: Int,
        defaultColor: Int
    ) {
        if (lstDataColor.size > currNumber) {
                paint.color = lstDataColor[currNumber]
            } else {
                paint.color = defaultColor
            }
    }

    /**
     * 返回当前点击点的信息
     * @param x 点击点X坐标
     * @param y    点击点Y坐标
     * @return 返回对应的位置记录
     */
    fun getPositionRecord(x: Float, y: Float): BarPosition? {
        return selectHelper?.getBarRecord(x, y)
    }

     fun saveBarRectFRecord(
        dataID: Int, childID: Int, left: Float,
        top: Float, right: Float, bottom: Float
    ) {
        if (adapter.isRecordSetInited) return

        val pRecord = PlotBarPosition()
        pRecord.savePlotDataID(dataID)
        pRecord.savePlotDataChildID(childID)
        pRecord.savePlotRectF(left, top, right, bottom)
        //pRecord.extPointClickRange(clickRangeExtValue)
        adapter.addRecordItem(pRecord)
    }

    protected open fun getCateTickCount(categoryAxis:CategoryLineAxis): Int {
        var count: Int = categoryAxis.dataSet.size
        if (ChartEnum.BarCenterStyle.SPACE != barCenterStyle) count += 1
        return count
    }


    protected open fun get3DOffsetX(): Float {
        return 0.0f
    }


    protected open fun get3DBaseOffsetX(): Float // 分类		
    {
        return 0.0f
    }

    protected open fun get3DBaseOffsetY(): Float // 分类		
    {
        return 0.0f
    }
}